package gsd.gaudi.client.anonymizer;

import gsd.gaudi.common.GaudiException;
import gsd.gaudi.common.GaudiGuiHierarchy;
import gsd.gaudi.common.GaudiReport;
import gsd.gaudi.common.model.log.GaudiEvent;
import gsd.gaudi.common.model.log.GaudiEventSequence;

import java.awt.AWTEvent;
import java.awt.AWTException;
import java.awt.Component;
import java.awt.Robot;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.WindowEvent;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInput;
import java.io.ObjectInputStream;

import javax.swing.JTextField;

public class GaudiEventReplayer extends GaudiReplayer{

	private String name;
	private GaudiEventSequence sequence;
	private GaudiException exception;
	private Robot robot;
	private GaudiGuiHierarchy hierarchy;
	public GaudiGuiHierarchy getHierarchy() {
		return hierarchy;
	}

	public void setHierarchy(GaudiGuiHierarchy hierarchy) {
		this.hierarchy = hierarchy;
	}

	private String lastWidgetClicked = "";
	private ReplayerMonitor monitor;
	
	
	public GaudiEventReplayer(String name){
		this.name = name;
		this.hierarchy = new GaudiGuiHierarchy();
		
		try {
			Thread.sleep(4000);
		} catch (InterruptedException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		
		this.hierarchy.processGUI();
		this.monitor = new ReplayerMonitor(this);		
		
		InputStream file;
		try {
			
			file = new FileInputStream(name);
			InputStream buffer = new BufferedInputStream(file);
			ObjectInput input = new ObjectInputStream (buffer);
			GaudiReport report = (GaudiReport) input.readObject();
			
			this.sequence = report.getSequence();
			this.exception = report.getException();
			
			this.robot = new Robot();
		
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (AWTException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
	public void replayEventSequence(){
		
		System.out.println("[GaudiServer]->Replaying execution which led to " + 
								this.exception.getException().getMessage());
			
		for(GaudiEvent e : this.sequence.getEventseq()){
		
			Component c = this.hierarchy.findWidget(e.widgetid);

			int index = 0;
			while(c == null && index < 2){
				try {
					Thread.sleep(200);
				} catch (InterruptedException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
				c = this.hierarchy.findWidget(e.widgetid);
				index++;
			}
			if(c == null){
				break;
			}
			
			
			if(e.id == MouseEvent.MOUSE_PRESSED){
				this.lastWidgetClicked = e.widgetid;
			}
			
			if(e.id == MouseEvent.MOUSE_PRESSED ||
					e.id == MouseEvent.MOUSE_RELEASED){
				AWTEvent newe = new MouseEvent(c,
											   e.id,
											   e.when,
											   e.modifiers,
											   0,
											   0,
											   e.clickcount,
											   false,
											   e.buttonclick);
				//newe.setSource(c);
				c.dispatchEvent(newe);
				
				if(e.id == MouseEvent.MOUSE_PRESSED)
					System.out.println("[GaudiServer]--> Replaying mouse pressed event at " + e.widgetid);
				else
					System.out.println("[GaudiServer]--> Replaying mouse release event at " + e.widgetid);
				
				//this.dmouse.drawMouse(c);
			}else if (e.id == KeyEvent.KEY_PRESSED){
				this.robot.keyPress(e.keycode);
				
				System.out.println("[GaudiServer]--> Replaying key pressed event at " + e.widgetid);

			}else if (e.id == KeyEvent.KEY_RELEASED){
				this.robot.keyRelease(e.keycode);
				
				System.out.println("[GaudiServer]--> Replaying key released event at " + e.widgetid);

			}else if (e.id == GaudiEvent.SET_TEXT_JTEXTFIELD){
				
				System.out.println("[GaudiServer]--> Replaying a set text at " + e.widgetid);
				
				JTextField text = (JTextField)c;
				text.setText(e.text);
			}


		}
		
		System.err.println("###FINITO####");
	}

	public void processEvent(AWTEvent arg0) {
		
		if(arg0.getID() == WindowEvent.WINDOW_ACTIVATED && !this.lastWidgetClicked.equals("")){	
			if (this.hierarchy.findWidgetId((Component) arg0.getSource()) == null &&
				this.hierarchy.findWidget(this.lastWidgetClicked + "/0") == null){
				
				this.hierarchy.processWidget((Component) arg0.getSource(), this.lastWidgetClicked + "/0");
				
			}else if (this.hierarchy.findWidgetId((Component) arg0.getSource()) == null &&
					  this.hierarchy.findWidget(this.lastWidgetClicked + "/0") != null){
				
				this.hierarchy.updateWidget((Component) arg0.getSource(), this.lastWidgetClicked + "/0");
			
			}
		}
		
	}
}
